Aller au contenu principal

Recherche de chemin

Le module board fournit des fonctions de recherche de chemin, pour faciliter le développement de comportements complexes sur le plateau.

BoardPosition​

Cet objet représente des coordonnées sur le plateau. Il stocke :

  • les coordonnées (x, y) sur le plateau, sous forme d'entiers
  • l'orientation à cette position (TOP_LEFT, TOP, TOP_RIGHT, RIGHT, BOTTOM_RIGHT, BOTTOM, BOTTOM_LEFT, LEFT)
"""
Constructeur de la classe

:param x: coordonnée entière sur le plateau
:param y: coordonnée entière sur le plateau
"""
BoardPosition(x, y)

"""
Constructeur de la classe

:param x: coordonnée entière sur le plateau
:param y: coordonnée entière sur le plateau
:param orientation: constante du module
"""
BoardPosition(x, y, orientation)

"""
Constructeur de la classe

:param board_position: autre BoardPosition à copier
"""
BoardPosition(board_position)

"""
Renvoie la coordonnée x sur le plateau (entier)
"""
get_x()

"""
Renvoie la coordonnée y sur le plateau (entier)
"""
get_y()

"""
Renvoie l'orientation sur le plateau (constante)
"""
get_orientation()

"""
Renvoie un tableau [x, y, orientation]
"""
get()

"""
Modifie la coordonnée x

:param x: entier
"""
set_x(x)

"""
Modifie la coordonnée y

:param y: entier
"""
set_y(y)

"""
Modifie l'orientation

:param orientation: constante du module
"""
set_orientation(orientation)

"""
orientation est optionnel
"""
set(x, y, orientation)

"""
Ajoute les coordonnées x et y d'une autre position du plateau

:param board_position: objet BoardPosition
"""
add(board_position)

"""
Copie les valeurs x, y et orientation d'une autre position du plateau

:param board_position: objet BoardPosition
"""
copy(board_position)

"""
Se déplace d'une tuile dans la direction donnée, sur un plateau carré.

:param direction: TOP, RIGHT, BOTTOM, LEFT
"""
move_in_square_board(direction)

"""
Vérifie si les valeurs x, y et orientation sont égales à celles d'une autre BoardPosition

:param board_position: objet BoardPosition

Renvoie un booléen.
"""
is_equal(board_position)

"""
Affiche les valeurs internes dans le shell
"""
dump()

"""
Supprime l'objet
"""
__del__()

BoardPath​

Cet objet stocke un tableau de positions sur le plateau.

"""
Constructeur de la classe
"""
BoardPath()

"""
Ajoute une position au chemin

:param board_position: objet BoardPosition
"""
append(board_position)

"""
Renvoie le prochain point de passage du chemin

Renvoie un objet BoardPosition
"""
get_next_waypoint()

"""
Affiche tous les points de passage
"""
dump()

"""
Détruit l'objet
"""
__del__()

Pathfinder​

Sert à trouver un chemin entre deux points du plateau en évitant les éléments.

"""
Constructeur de la classe

:param board: objet Board
"""
Pathfinder(board)

"""
Trouve un chemin entre deux nœuds.

:param start: objet BoardPosition contenant les coordonnées du nœud de départ
:param end: objet BoardPosition contenant les coordonnées du nœud d'arrivée
:param is_node_walkable_callback: fonction appelée pour vérifier si on peut aller sur un nœud

Renvoie un BoardPath
"""
find_path_to_node(start, end, is_node_walkable_callback)

"""
Détruit l'objet
"""
__del__()

Exemples​

Exemple simple​

import olem
import genericboard

TYPE_START = "start"
TYPE_END = "end"
TYPE_WALL = "wall"

def move_to_board_position(start, position):
y_phys = (position.get_x() - start.get_x()) * 70
x_phys = - (position.get_y() - start.get_y()) * 70

print("(" + str(position.get_x()) + ", " + str(position.get_y()) + ") (" + str(x_phys) + ", " + str(y_phys) + ")")
olem.move_to(x_phys, y_phys, 0)

def find_start_pos(board):
columns = board.get_column_count()
rows = board.get_row_count()

for y in range(rows):
for x in range(columns):
tile = board.get_tile(x, y)
node = tile.get_node()

if (node.has_element_type(TYPE_START)):
return genericboard.BoardPosition(x, y)

def find_end_pos(board):
columns = board.get_column_count()
rows = board.get_row_count()

for y in range(rows):
for x in range(columns):
tile = board.get_tile(x, y)
node = tile.get_node()

if (node.has_element_type(TYPE_END)):
return genericboard.BoardPosition(x, y)

def node_walkable_callback(board, x, y):
# Vérifier si on est au bord du plateau
if (
not board.is_position_within_board(x, y)
or not board.is_position_within_board(x - 1, y)
or not board.is_position_within_board(x, y - 1)
):
return False

if (board.get_column_count() - 1 == x or board.get_row_count() - 1 == y):
return False

# Vérifier maintenant le contenu du plateau
tile = board.get_tile(x, y)
if (
tile.get_node().has_element_type(TYPE_WALL)
or tile.get_border(0).has_element_type(TYPE_WALL)
or tile.get_border(1).has_element_type(TYPE_WALL)
):
return False

tile = board.get_tile(x - 1, y)
if tile.get_border(0).has_element_type(TYPE_WALL):
return False

tile = board.get_tile(x, y - 1)
if tile.get_border(1).has_element_type(TYPE_WALL):
return False

return True

board = genericboard.load_board("/tmp/board_tester")
board.print()

start = find_start_pos(board)
end = find_end_pos(board)

pf = genericboard.Pathfinder(board)

path = pf.find_path_to_node(start, end, node_walkable_callback)
path.dump()

current_position = genericboard.BoardPosition(start)
while not end.is_equal(current_position):
current_position = path.get_next_waypoint()
move_to_board_position(start, current_position)
olem.wait_stop_moving()

#path.__del__()
#pf.__del__()
#board.__del__()